//+------------------------------------------------------------------+
//|                                            DualEngine_EA.mq5    |
//|                        Copyright 2025, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property description "双引擎EA系统 - 马丁格尔+趋势跟踪"

#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\OrderInfo.mqh>

//--- 全局交易对象
CTrade         trade;
CPositionInfo  position;
COrderInfo     order;

//--- 输入参数
input group "=== 基础参数 ==="
input double   InitialLot      = 0.01;       // 起始手数
input double   Multiplier      = 1.5;        // 加仓倍数
input int      MaxLayers       = 8;          // 最大层数
input double   HedgeRatio      = 0.6;        // 对冲比例
input int      MagicNumber     = 123456;     // 魔术数字

input group "=== 技术参数 ==="
input double   ATRMultiplier   = 2.5;        // 均线偏离ATR倍数
input int      ADXPeriod       = 14;         // ADX周期
input double   ADXThreshold    = 35;         // ADX单边阈值
input int      ATRPeriod       = 14;         // ATR周期
input int      FastMA          = 34;         // 快速均线周期
input int      SlowMA          = 89;         // 慢速均线周期
input double   MartinDistanceATR = 1.5;      // 马丁加仓距离(ATR倍数)
input double   MartinTPPercent = 0.01;       // 马丁整体止盈百分比(1%)
input double   MartinTPATR     = 3.0;        // 马丁均价止盈(ATR倍数)
input double   TrendTPATR      = 2.0;        // 趋势止盈回调(ATR倍数)

input group "=== 风控参数 ==="
input double   DrawdownLevel1  = 0.03;       // 回撤等级1(3%)
input double   DrawdownLevel2  = 0.05;       // 回撤等级2(5%)
input double   MaxRiskPercent  = 0.2;        // 最大风险百分比

//--- 全局变量
double         reserveFund = 0;               // 风险准备金
int            martinLayers = 0;              // 当前马丁层数
datetime       lastTradeTime = 0;            // 最后交易时间
double         lastMartinPrice = 0;           // 最后马丁开仓价格
double         martinAvgPrice = 0;            // 马丁平均价格
double         trendHighPrice = 0;            // 趋势最高价记录
double         trendLowPrice = 0;             // 趋势最低价记录

//--- 指标句柄
int            handleADX;
int            handleATR;
int            handleFastMA;
int            handleSlowMA;
int            handleBB;

//--- 缓冲区
double         adxBuffer[];
double         atrBuffer[];
double         fastMABuffer[];
double         slowMABuffer[];
double         bbUpperBuffer[];
double         bbLowerBuffer[];
double         bbMainBuffer[];

//+------------------------------------------------------------------+
//| 专家初始化函数                                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // 设置交易参数
   trade.SetExpertMagicNumber(MagicNumber);
   trade.SetMarginMode();
   trade.SetTypeFillingBySymbol(_Symbol);
   
   // 初始化指标
   if(!InitIndicators())
   {
      Print("指标初始化失败");
      return(INIT_FAILED);
   }
   
   // 初始化数组
   ArraySetAsSeries(adxBuffer, true);
   ArraySetAsSeries(atrBuffer, true);
   ArraySetAsSeries(fastMABuffer, true);
   ArraySetAsSeries(slowMABuffer, true);
   ArraySetAsSeries(bbUpperBuffer, true);
   ArraySetAsSeries(bbLowerBuffer, true);
   ArraySetAsSeries(bbMainBuffer, true);
   
   reserveFund = 0;
   martinLayers = 0;
   
   Print("双引擎EA系统初始化完成");
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| 初始化指标                                                       |
//+------------------------------------------------------------------+
bool InitIndicators()
{
   handleADX = iADX(_Symbol, PERIOD_CURRENT, ADXPeriod);
   handleATR = iATR(_Symbol, PERIOD_CURRENT, ATRPeriod);
   handleFastMA = iMA(_Symbol, PERIOD_CURRENT, FastMA, 0, MODE_EMA, PRICE_CLOSE);
   handleSlowMA = iMA(_Symbol, PERIOD_CURRENT, SlowMA, 0, MODE_EMA, PRICE_CLOSE);
   handleBB = iBands(_Symbol, PERIOD_CURRENT, 20, 0, 2, PRICE_CLOSE);
   
   if(handleADX == INVALID_HANDLE || handleATR == INVALID_HANDLE || 
      handleFastMA == INVALID_HANDLE || handleSlowMA == INVALID_HANDLE ||
      handleBB == INVALID_HANDLE)
   {
      return false;
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| 专家逆初始化函数                                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // 释放指标句柄
   if(handleADX != INVALID_HANDLE) IndicatorRelease(handleADX);
   if(handleATR != INVALID_HANDLE) IndicatorRelease(handleATR);
   if(handleFastMA != INVALID_HANDLE) IndicatorRelease(handleFastMA);
   if(handleSlowMA != INVALID_HANDLE) IndicatorRelease(handleSlowMA);
   if(handleBB != INVALID_HANDLE) IndicatorRelease(handleBB);
   
   Print("双引擎EA系统已停止");
}

//+------------------------------------------------------------------+
//| 主执行函数                                                       |
//+------------------------------------------------------------------+
void OnTick()
{
   // 更新指标数据
   if(!UpdateIndicatorData())
   {
      Print("指标数据更新失败");
      return;
   }
   
   // 更新市场状态
   UpdateMarketStatus();
   
   // 执行风控检查
   ExecuteRiskControl();
   
   // 策略引擎选择
   bool isTrending = IsTrendingMarket();
   Print("市场状态判断 - 趋势市场:", isTrending, " 当前层数:", martinLayers);
   
   if(isTrending)
   {
      Print("选择趋势引擎");
      TrendEngineExecute();    // 趋势行情模式
   }
   else
   {
      Print("选择马丁引擎");
      MartinEngineExecute();   // 震荡行情模式
   }
}

//+------------------------------------------------------------------+
//| 更新指标数据                                                     |
//+------------------------------------------------------------------+
bool UpdateIndicatorData()
{
   if(CopyBuffer(handleADX, 0, 0, 3, adxBuffer) <= 0) return false;
   if(CopyBuffer(handleATR, 0, 0, 3, atrBuffer) <= 0) return false;
   if(CopyBuffer(handleFastMA, 0, 0, 3, fastMABuffer) <= 0) return false;
   if(CopyBuffer(handleSlowMA, 0, 0, 3, slowMABuffer) <= 0) return false;
   if(CopyBuffer(handleBB, 0, 0, 3, bbUpperBuffer) <= 0) return false;
   if(CopyBuffer(handleBB, 1, 0, 3, bbLowerBuffer) <= 0) return false;
   if(CopyBuffer(handleBB, 2, 0, 3, bbMainBuffer) <= 0) return false;
   
   return true;
}

//+------------------------------------------------------------------+
//| 市场状态识别模块                                                 |
//+------------------------------------------------------------------+
bool IsTrendingMarket()
{
   double adx = adxBuffer[0];
   double bollWidth = CalculateBollingerWidth();
   double orderFlow = GetOrderFlowImbalance();
   
   // 单边行情判定（满足两个条件即可）
   int conditionCount = 0;
   
   bool adxOK = (adx > ADXThreshold);
   bool bollOK = (bollWidth > 1.2);
   bool flowOK = (MathAbs(orderFlow) > 0.6);
   
   if(adxOK) conditionCount++;
   if(bollOK) conditionCount++;
   if(flowOK) conditionCount++;
   
   Print("市场识别 - ADX:", adx, "(", ADXThreshold, ")=", adxOK, 
         " 布林宽度:", bollWidth, "(1.2)=", bollOK,
         " 订单流:", orderFlow, "=", flowOK,
         " 满足条件:", conditionCount, "/3");
   
   return (conditionCount >= 2);
}

//+------------------------------------------------------------------+
//| 计算布林带宽度                                                   |
//+------------------------------------------------------------------+
double CalculateBollingerWidth()
{
   double upper = bbUpperBuffer[0];
   double lower = bbLowerBuffer[0];
   double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   
   if(currentPrice > 0)
      return ((upper - lower) / currentPrice) * 100;
   
   return 0;
}

//+------------------------------------------------------------------+
//| 获取订单流不平衡度                                               |
//+------------------------------------------------------------------+
double GetOrderFlowImbalance()
{
   MqlTick lastTick;
   if(!SymbolInfoTick(_Symbol, lastTick))
      return 0;
   
   double buyVolume = lastTick.volume;
   double sellVolume = lastTick.volume;
   
   // 简化版本：根据价格变化判断买卖压力
   if(lastTick.bid > lastTick.ask)
      return 0.3;  // 买方压力
   else if(lastTick.bid < lastTick.ask)
      return -0.3; // 卖方压力
   
   return 0;
}

//+------------------------------------------------------------------+
//| 更新市场状态                                                     |
//+------------------------------------------------------------------+
void UpdateMarketStatus()
{
   martinLayers = CountMartinLayers();
}

//+------------------------------------------------------------------+
//| 计算马丁层数                                                     |
//+------------------------------------------------------------------+
int CountMartinLayers()
{
   int count = 0;
   for(int i = 0; i < PositionsTotal(); i++)
   {
      if(position.SelectByIndex(i))
      {
         if(position.Symbol() == _Symbol && position.Magic() == MagicNumber)
         {
            count++;
         }
      }
   }
   return count;
}

//+------------------------------------------------------------------+
//| 马丁格尔引擎                                                     |
//+------------------------------------------------------------------+
void MartinEngineExecute()
{
   // 先检查马丁止盈条件
   if(CheckMartinTakeProfit())
   {
      CloseAllMartinPositions();
      return;
   }
   
   // 检查是否需要加仓
   if(ShouldAddMartinLayer())
   {
      AddMartinLayer();
   }
}

//+------------------------------------------------------------------+
//| 加仓条件检查                                                     |
//+------------------------------------------------------------------+
bool ShouldAddMartinLayer()
{
   // 层数限制
   if(martinLayers >= MaxLayers) 
   {
      Print("马丁层数已达上限: ", martinLayers);
      return false;
   }
   
   // 波动率过滤
   if(GetCurrentATR() > GetAverageATR() * 1.2) 
   {
      Print("波动率过高，暂停交易. 当前ATR:", GetCurrentATR(), " 平均ATR:", GetAverageATR());
      return false;
   }
   
   // 订单流过滤
   if(MathAbs(GetOrderFlowImbalance()) > 0.7) 
   {
      Print("订单流不平衡过大: ", GetOrderFlowImbalance());
      return false;
   }
   
   // 价格距离过滤（马丁加仓距离）
   if(martinLayers > 0 && lastMartinPrice > 0)
   {
      double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
      double priceDistance = MathAbs(currentPrice - lastMartinPrice);
      double requiredDistance = GetCurrentATR() * MartinDistanceATR;
      
      if(priceDistance < requiredDistance)
      {
         Print("价格距离不足，当前距离:", priceDistance, " 需要距离:", requiredDistance);
         return false;
      }
   }
   
   // 修改逻辑：允许初始开仓或存在亏损持仓时加仓
   if(martinLayers == 0)
   {
      Print("准备进行初始开仓");
      return true;  // 允许初始开仓
   }
   else if(HasLosingPosition())
   {
      Print("检测到亏损持仓，准备加仓");
      return true;  // 有亏损持仓时加仓
   }
   
   Print("无开仓条件，当前层数:", martinLayers, " 是否有亏损:", HasLosingPosition());
   return false;
}

//+------------------------------------------------------------------+
//| 检查马丁止盈条件                                                 |
//+------------------------------------------------------------------+
bool CheckMartinTakeProfit()
{
   if(martinLayers == 0) return false;
   
   double totalProfit = GetTotalFloatingPL();
   double equity = AccountInfoDouble(ACCOUNT_EQUITY);
   double profitPercent = totalProfit / equity;
   
   // 条件1：整体盈利达到设定百分比
   if(profitPercent >= MartinTPPercent)
   {
      Print("马丁整体盈利止盈 - 盈利:", totalProfit, " 百分比:", profitPercent*100, "%");
      return true;
   }
   
   // 条件2：均价盈利达到设定ATR倍数
   if(martinAvgPrice > 0)
   {
      double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
      int direction = GetMainPositionDirection();
      double atr = GetCurrentATR();
      double profitDistance = 0;
      
      if(direction > 0) // 多头持仓
      {
         profitDistance = currentPrice - martinAvgPrice;
      }
      else if(direction < 0) // 空头持仓
      {
         profitDistance = martinAvgPrice - currentPrice;
      }
      
      double requiredProfit = atr * MartinTPATR;
      
      if(profitDistance >= requiredProfit)
      {
         Print("马丁均价止盈 - 盈利距离:", profitDistance, " 需要距离:", requiredProfit);
         return true;
      }
      
      Print("马丁止盈检查 - 当前盈利:", profitDistance, "/", requiredProfit, " 百分比:", profitPercent*100, "%");
   }
   
   return false;
}

//+------------------------------------------------------------------+
//| 平仓所有马丁持仓                                                 |
//+------------------------------------------------------------------+
void CloseAllMartinPositions()
{
   Print("开始平仓所有马丁持仓");
   
   for(int i = PositionsTotal() - 1; i >= 0; i--)
   {
      if(position.SelectByIndex(i))
      {
         if(position.Symbol() == _Symbol && position.Magic() == MagicNumber)
         {
            if(trade.PositionClose(position.Ticket()))
            {
               Print("平仓成功 - 票号:", position.Ticket(), " 盈利:", position.Profit());
            }
            else
            {
               Print("平仓失败 - 票号:", position.Ticket(), " 错误:", trade.ResultRetcode());
            }
         }
      }
   }
   
   // 重置马丁相关变量
   martinLayers = 0;
   lastMartinPrice = 0;
   martinAvgPrice = 0;
   
   Print("马丁持仓全部平仓完成");
}

//+------------------------------------------------------------------+
//| 检查是否有亏损持仓                                               |
//+------------------------------------------------------------------+
bool HasLosingPosition()
{
   for(int i = 0; i < PositionsTotal(); i++)
   {
      if(position.SelectByIndex(i))
      {
         if(position.Symbol() == _Symbol && position.Magic() == MagicNumber)
         {
            if(position.Profit() < 0)
               return true;
         }
      }
   }
   return false;
}

//+------------------------------------------------------------------+
//| 添加马丁层                                                       |
//+------------------------------------------------------------------+
void AddMartinLayer()
{
   double lotSize = CalculateMartinLot(martinLayers);
   int direction = GetMainPositionDirection();
   
   Print("准备开仓 - 层数:", martinLayers, " 手数:", lotSize, " 方向:", direction);
   
   if(direction == 0) // 没有持仓，开新仓
   {
      // 根据价格与均线关系决定方向
      double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
      double slowMA = slowMABuffer[0];
      
      Print("初始开仓判断 - 价格:", price, " 慢线:", slowMA);
      
      if(price > slowMA)
      {
         Print("价格高于慢线，开空仓(逆向马丁)");
         if(OpenPosition(ORDER_TYPE_SELL, lotSize))
         {
            lastMartinPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
         }
      }
      else
      {
         Print("价格低于慢线，开多仓(逆向马丁)");
         if(OpenPosition(ORDER_TYPE_BUY, lotSize))
         {
            lastMartinPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
         }
      }
   }
   else
   {
      // 继续马丁方向
      ENUM_ORDER_TYPE orderType = (direction > 0) ? ORDER_TYPE_BUY : ORDER_TYPE_SELL;
      Print("继续马丁方向 - 主方向:", direction, " 订单类型:", orderType);
      
      if(OpenPosition(orderType, lotSize))
      {
         if(orderType == ORDER_TYPE_BUY)
            lastMartinPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
         else
            lastMartinPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
      }
   }
   
   lastTradeTime = TimeCurrent();
   CalculateMartinAvgPrice(); // 重新计算平均价格
}

//+------------------------------------------------------------------+
//| 计算马丁手数                                                     |
//+------------------------------------------------------------------+
double CalculateMartinLot(int layer)
{
   double lot = InitialLot * MathPow(Multiplier, layer);
   
   // 手数规范化
   double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
   double stepLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
   
   lot = MathMax(lot, minLot);
   lot = MathMin(lot, maxLot);
   lot = NormalizeDouble(lot / stepLot, 0) * stepLot;
   
   return lot;
}

//+------------------------------------------------------------------+
//| 计算马丁平均价格                                                 |
//+------------------------------------------------------------------+
void CalculateMartinAvgPrice()
{
   double totalVolume = 0;
   double weightedPrice = 0;
   
   for(int i = 0; i < PositionsTotal(); i++)
   {
      if(position.SelectByIndex(i))
      {
         if(position.Symbol() == _Symbol && position.Magic() == MagicNumber)
         {
            totalVolume += position.Volume();
            weightedPrice += position.PriceOpen() * position.Volume();
         }
      }
   }
   
   if(totalVolume > 0)
   {
      martinAvgPrice = weightedPrice / totalVolume;
      Print("马丁平均价格更新:", martinAvgPrice, " 总手数:", totalVolume);
   }
   else
   {
      martinAvgPrice = 0;
      lastMartinPrice = 0;
   }
}

//+------------------------------------------------------------------+
//| 获取主要持仓方向                                                 |
//+------------------------------------------------------------------+
int GetMainPositionDirection()
{
   double totalBuy = 0, totalSell = 0;
   
   for(int i = 0; i < PositionsTotal(); i++)
   {
      if(position.SelectByIndex(i))
      {
         if(position.Symbol() == _Symbol && position.Magic() == MagicNumber)
         {
            if(position.PositionType() == POSITION_TYPE_BUY)
               totalBuy += position.Volume();
            else
               totalSell += position.Volume();
         }
      }
   }
   
   if(totalBuy > totalSell) return 1;  // 多头为主
   if(totalSell > totalBuy) return -1; // 空头为主
   return 0; // 无持仓
}

//+------------------------------------------------------------------+
//| 趋势跟踪引擎                                                     |
//+------------------------------------------------------------------+
void TrendEngineExecute()
{
   // 更新趋势价格记录
   UpdateTrendPriceRecord();
   
   // 检查趋势回调止盈
   if(CheckTrendTakeProfit())
   {
      CloseAllTrendPositions();
      return;
   }
   
   if(ShouldOpenTrendPosition())
   {
      OpenTrendPosition();
   }
}

//+------------------------------------------------------------------+
//| 趋势开仓条件检查                                                 |
//+------------------------------------------------------------------+
bool ShouldOpenTrendPosition()
{
   double fastMA = fastMABuffer[0];
   double slowMA = slowMABuffer[0];
   double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double atr = GetCurrentATR();
   
   // 计算价格偏离值
   double deviation = MathAbs(price - slowMA) / atr;
   
   // 趋势条件
   bool isUptrend = (price > slowMA) && (price > fastMA);
   bool isDowntrend = (price < slowMA) && (price < fastMA);
   
   Print("趋势检查 - 价格:", price, " 快线:", fastMA, " 慢线:", slowMA, " ATR:", atr);
   Print("偏离倍数:", deviation, " 需要:", ATRMultiplier, " 上涨:", isUptrend, " 下跌:", isDowntrend);
   
   // 检查是否已有趋势仓位
   if(HasTrendPosition()) 
   {
      Print("已有持仓，不开趋势仓");
      return false;
   }
   
   // 降低偏离要求，使更容易开仓
   bool deviationOK = (deviation > ATRMultiplier * 0.7); // 降低到70%
   bool trendOK = isUptrend || isDowntrend;
   
   Print("偏离条件:", deviationOK, " 趋势条件:", trendOK);
   
   return deviationOK && trendOK;
}

//+------------------------------------------------------------------+
//| 检查是否有趋势仓位（用于开仓判断）                               |
//+------------------------------------------------------------------+
bool HasTrendPosition()
{
   // 简化：如果马丁层数为0，可以开趋势仓
   return (martinLayers > 0);
}

//+------------------------------------------------------------------+
//| 开趋势仓位                                                       |
//+------------------------------------------------------------------+
void OpenTrendPosition()
{
   double lotSize = CalculateTrendLotSize();
   double fastMA = fastMABuffer[0];
   double slowMA = slowMABuffer[0];
   double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   
   ENUM_ORDER_TYPE orderType;
   if(price > slowMA && price > fastMA)
      orderType = ORDER_TYPE_BUY;
   else if(price < slowMA && price < fastMA)
      orderType = ORDER_TYPE_SELL;
   else
      return;
   
   if(OpenPosition(orderType, lotSize))
   {
      // 初始化趋势价格记录
      trendHighPrice = price;
      trendLowPrice = price;
      Print("趋势仓位开仓成功，初始化价格记录:", price);
   }
}

//+------------------------------------------------------------------+
//| 计算趋势仓位手数                                                 |
//+------------------------------------------------------------------+
double CalculateTrendLotSize()
{
   double martinLots = GetTotalMartinLots();
   double equityRisk = AccountInfoDouble(ACCOUNT_EQUITY) * 0.002;
   double atr = GetCurrentATR();
   double pointValue = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
   
   double atrRisk = (atr / pointValue) * SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
   
   double lotByMartin = martinLots * 0.3;
   double lotByRisk = (atrRisk > 0) ? equityRisk / atrRisk : InitialLot;
   
   double lot = MathMin(lotByMartin, lotByRisk);
   if(lot <= 0) lot = InitialLot;
   
   return NormalizeLot(lot);
}

//+------------------------------------------------------------------+
//| 获取马丁总手数                                                   |
//+------------------------------------------------------------------+
double GetTotalMartinLots()
{
   double totalLots = 0;
   
   for(int i = 0; i < PositionsTotal(); i++)
   {
      if(position.SelectByIndex(i))
      {
         if(position.Symbol() == _Symbol && position.Magic() == MagicNumber)
         {
            totalLots += position.Volume();
         }
      }
   }
   
   return totalLots;
}

//+------------------------------------------------------------------+
//| 更新趋势价格记录                                                 |
//+------------------------------------------------------------------+
void UpdateTrendPriceRecord()
{
   if(HasTrendPositions())
   {
      double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
      
      if(currentPrice > trendHighPrice || trendHighPrice == 0)
      {
         trendHighPrice = currentPrice;
      }
      
      if(currentPrice < trendLowPrice || trendLowPrice == 0)
      {
         trendLowPrice = currentPrice;
      }
   }
}

//+------------------------------------------------------------------+
//| 检查是否有趋势持仓                                               |
//+------------------------------------------------------------------+
bool HasTrendPositions()
{
   // 简化判断：如果马丁层数为0且有持仓，则认为是趋势持仓
   return (martinLayers == 0 && PositionsTotal() > 0);
}

//+------------------------------------------------------------------+
//| 检查趋势止盈条件                                                 |
//+------------------------------------------------------------------+
bool CheckTrendTakeProfit()
{
   if(!HasTrendPositions()) return false;
   
   double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double atr = GetCurrentATR();
   double retraceThreshold = atr * TrendTPATR;
   
   int direction = GetMainPositionDirection();
   bool shouldClose = false;
   
   if(direction > 0) // 多头持仓
   {
      // 检查是否从最高价回调超过阈值
      if(trendHighPrice > 0)
      {
         double retrace = trendHighPrice - currentPrice;
         if(retrace >= retraceThreshold)
         {
            Print("多头趋势回调止盈 - 最高价:", trendHighPrice, " 当前价:", currentPrice, " 回调:", retrace, " 阈值:", retraceThreshold);
            shouldClose = true;
         }
      }
   }
   else if(direction < 0) // 空头持仓
   {
      // 检查是否从最低价反弹超过阈值
      if(trendLowPrice > 0)
      {
         double retrace = currentPrice - trendLowPrice;
         if(retrace >= retraceThreshold)
         {
            Print("空头趋势回调止盈 - 最低价:", trendLowPrice, " 当前价:", currentPrice, " 反弹:", retrace, " 阈值:", retraceThreshold);
            shouldClose = true;
         }
      }
   }
   
   return shouldClose;
}

//+------------------------------------------------------------------+
//| 平仓所有趋势持仓                                                 |
//+------------------------------------------------------------------+
void CloseAllTrendPositions()
{
   Print("开始平仓所有趋势持仓");
   
   for(int i = PositionsTotal() - 1; i >= 0; i--)
   {
      if(position.SelectByIndex(i))
      {
         if(position.Symbol() == _Symbol && position.Magic() == MagicNumber)
         {
            if(trade.PositionClose(position.Ticket()))
            {
               Print("趋势平仓成功 - 票号:", position.Ticket(), " 盈利:", position.Profit());
            }
            else
            {
               Print("趋势平仓失败 - 票号:", position.Ticket(), " 错误:", trade.ResultRetcode());
            }
         }
      }
   }
   
   // 重置趋势相关变量
   trendHighPrice = 0;
   trendLowPrice = 0;
   
   Print("趋势持仓全部平仓完成");
}



//+------------------------------------------------------------------+
//| 开仓函数                                                         |
//+------------------------------------------------------------------+
bool OpenPosition(ENUM_ORDER_TYPE orderType, double lot)
{
   double price;
   
   if(orderType == ORDER_TYPE_BUY)
      price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   else
      price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   
   lot = NormalizeLot(lot);
   
   Print("执行开仓 - 类型:", orderType, " 手数:", lot, " 价格:", price);
   
   bool result = trade.PositionOpen(_Symbol, orderType, lot, price, 0, 0, "DualEngine EA");
   
   if(result)
   {
      Print("开仓成功！");
   }
   else
   {
      Print("开仓失败！错误代码:", trade.ResultRetcode(), " 描述:", trade.ResultRetcodeDescription());
   }
   
   return result;
}

//+------------------------------------------------------------------+
//| 手数规范化                                                       |
//+------------------------------------------------------------------+
double NormalizeLot(double lot)
{
   double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
   double stepLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
   
   lot = MathMax(lot, minLot);
   lot = MathMin(lot, maxLot);
   lot = NormalizeDouble(lot / stepLot, 0) * stepLot;
   
   return lot;
}

//+------------------------------------------------------------------+
//| 风控执行模块                                                     |
//+------------------------------------------------------------------+
void ExecuteRiskControl()
{
   double totalFloating = GetTotalFloatingPL();
   double equity = AccountInfoDouble(ACCOUNT_EQUITY);
   double equityPercent = MathAbs(totalFloating) / equity;
   
   if(equityPercent > DrawdownLevel2)
   {
      // 执行动态止损
      double stopDistance = CalculateDynamicStop();
      ApplyDynamicStopLoss(stopDistance);
   }
   else if(equityPercent > DrawdownLevel1)
   {
      // 执行非对称对冲
      ExecuteAsymmetricHedge();
   }
   
   // 更新准备金
   UpdateReserveFund();
}

//+------------------------------------------------------------------+
//| 获取浮动盈亏                                                     |
//+------------------------------------------------------------------+
double GetTotalFloatingPL()
{
   double totalPL = 0;
   
   for(int i = 0; i < PositionsTotal(); i++)
   {
      if(position.SelectByIndex(i))
      {
         if(position.Symbol() == _Symbol && position.Magic() == MagicNumber)
         {
            totalPL += position.Profit() + position.Swap() + position.Commission();
         }
      }
   }
   
   return totalPL;
}

//+------------------------------------------------------------------+
//| 计算动态止损距离                                                 |
//+------------------------------------------------------------------+
double CalculateDynamicStop()
{
   double atr = GetCurrentATR();
   double maxDrawdown = 0;
   
   // 获取最近20根K线的最大价格范围
   for(int i = 1; i <= 20; i++)
   {
      double high = iHigh(_Symbol, PERIOD_CURRENT, i);
      double low = iLow(_Symbol, PERIOD_CURRENT, i);
      double range = high - low;
      if(range > maxDrawdown) maxDrawdown = range;
   }
   
   return (atr * 3) + maxDrawdown;
}

//+------------------------------------------------------------------+
//| 非对称对冲执行                                                   |
//+------------------------------------------------------------------+
void ExecuteAsymmetricHedge()
{
   double totalLots = GetTotalMartinLots();
   int direction = GetMainPositionDirection();
   
   if(totalLots <= 0 || direction == 0) return;
   
   // 计算对冲手数（原方向的60%）
   double hedgeLots = totalLots * HedgeRatio;
   
   ENUM_ORDER_TYPE hedgeType = (direction > 0) ? ORDER_TYPE_SELL : ORDER_TYPE_BUY;
   
   // 开对冲仓
   if(OpenPosition(hedgeType, hedgeLots))
   {
      Print("执行非对称对冲，手数: ", hedgeLots);
   }
}

//+------------------------------------------------------------------+
//| 应用动态止损                                                     |
//+------------------------------------------------------------------+
void ApplyDynamicStopLoss(double stopDistance)
{
   for(int i = PositionsTotal() - 1; i >= 0; i--)
   {
      if(position.SelectByIndex(i))
      {
         if(position.Symbol() == _Symbol && position.Magic() == MagicNumber)
         {
            double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
            
            double stopLevel;
            if(position.PositionType() == POSITION_TYPE_BUY)
               stopLevel = currentPrice - stopDistance;
            else
               stopLevel = currentPrice + stopDistance;
            
            // 修改止损位
            trade.PositionModify(position.Ticket(), stopLevel, position.TakeProfit());
         }
      }
   }
}

//+------------------------------------------------------------------+
//| 更新准备金                                                       |
//+------------------------------------------------------------------+
void UpdateReserveFund()
{
   // 从盈利中提取准备金
   double totalProfit = 0;
   
   for(int i = 0; i < PositionsTotal(); i++)
   {
      if(position.SelectByIndex(i))
      {
         if(position.Symbol() == _Symbol && position.Magic() == MagicNumber)
         {
            if(position.Profit() > 0)
               totalProfit += position.Profit();
         }
      }
   }
   
   // 从盈利的30%中提取准备金
   if(totalProfit > 0)
   {
      reserveFund += totalProfit * 0.3;
   }
}

//+------------------------------------------------------------------+
//| 获取当前ATR                                                      |
//+------------------------------------------------------------------+
double GetCurrentATR()
{
   return atrBuffer[0];
}

//+------------------------------------------------------------------+
//| 获取平均ATR                                                      |
//+------------------------------------------------------------------+
double GetAverageATR()
{
   double sum = 0;
   int count = MathMin(50, ArraySize(atrBuffer));
   
   for(int i = 0; i < count; i++)
   {
      sum += atrBuffer[i];
   }
   
   return (count > 0) ? sum / count : GetCurrentATR();
}

//+------------------------------------------------------------------+
//| 专家函数结束                                                     |
//+------------------------------------------------------------------+ 